﻿using System;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Globalization;
using System.ComponentModel;

namespace Lswweb.Controls
{

    public class CallbackDropDownList: ControlBase,ICallbackEventHandler
    {
        /// <summary>
        /// 对dropdownlist进行绑定
        /// 当同时使用CallDropDownList和Fckeditor 并给Fckeditor.Value属性赋值时，需要设置 ValidateRequest="false"
        /// </summary>
        public event ObjectDataSourceObjectEventHandler DataSourceEventHandler;
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            Page.ClientScript.RegisterHiddenField(DropDownListValueInputId, string.Empty);
            if (!string.IsNullOrEmpty(SelectPath))
                Page.ClientScript.RegisterStartupScript(typeof(CallbackDropDownList), DropDownListValueInputId, "$(\"#" + DropDownListValueInputId + "\").val(\"" + SelectPath + "\");", true);
            else
                Page.ClientScript.RegisterStartupScript(typeof(CallbackDropDownList), this.ClientID, "$(function(){$(\"#" + SpanId + " select:first\").change();});", true);
            Page.ClientScript.RegisterClientScriptBlock(typeof(CallbackDropDownList),"CallbackScript", CallbackScript(), true);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Id,SpanId);
            if(!string.IsNullOrEmpty(Style))
                writer.AddAttribute(HtmlTextWriterAttribute.Style,Style);
            writer.RenderBeginTag(HtmlTextWriterTag.Span);
            writer.Write(RenderHTML());
            writer.RenderEndTag();
        }

        protected string CallbackScript()
        {
            StringBuilder script = new StringBuilder();
            script.Append("function GetCallBack(returnStr,context){");
            script.Append("$(context).nextAll().remove();");
            script.Append("var label=returnStr.split('|');");
            script.Append("$(\"#\" + label[1]).val(\"\");");
            script.Append("if(label[0].length>0){");
            script.Append("$(\"#\" + label[2]).append(label[0]);");
            script.Append("setTimeout(\"$('#\" + label[2] + \" select:last-child').change()\",1);");
            script.Append("}");
            script.Append("else{");
            script.Append("var controls=$(\"#\" + label[2] + \" > select\");");
            script.Append("for(var a=0;a<controls.length;a++)$(\"#\" + label[1]).val($(\"#\" + label[1]).val() + $(controls[a]).val() + \"/\");}");
            script.Append("}");
            return script.ToString();
        }

        protected string RenderHTML()
        {
            string html = string.Empty;
            string[] paths = SelectPath.Split('/');

            Control firstDDL =  GetDropDownList("0",paths[0]);
            html=GetControlHTML(firstDDL);

            if (string.IsNullOrEmpty(SelectPath))
                return html;

            for (int i = 0; i < paths.Length-1; i++)
            {
                Control ddl = GetDropDownList(paths[i],paths[i + 1]);
                html += GetControlHTML(ddl);
            }

            return html;
        }

        protected Control GetDropDownList(string parentSelectValue,string selectValue)
        {
            DropDownList ddl=new DropDownList();
            if (Rows > 1)
                ddl.Attributes.Add("size",Rows.ToString());
            if (!string.IsNullOrEmpty(DropDownListStyle))
                ddl.Attributes.Add("style", DropDownListStyle);
            if (DataSourceEventHandler != null)
            {
                ObjectDataSourceEventArgs args = new ObjectDataSourceEventArgs(parentSelectValue);
                DataSourceEventHandler(ddl,args);
            }

            if (ddl != null)
            {
                ddl.Attributes.Add("onchange", Page.ClientScript.GetCallbackEventReference(this, "$(this).val()", "GetCallBack", "this", null, true));


                if (!string.IsNullOrEmpty(selectValue))
                {
                    ListItem item = ddl.Items.FindByValue(selectValue);
                    if (item != null)
                    {
                        ddl.SelectedIndex = -1;
                        item.Selected = true;
                    }
                }
            }

            return (ddl.Items.Count>0)?ddl:null;
        }

        protected string GetControlHTML(Control control)
        {
            if (control == null)
                return string.Empty;

            StringWriter writer1 = new StringWriter(CultureInfo.InvariantCulture);
            HtmlTextWriter writer2 = new HtmlTextWriter(writer1);

            control.RenderControl(writer2);
            writer2.Flush();
            writer2.Close();

            return writer1.ToString();
        }

        #region ICallbackEventHandler 成员

        private string parentSelectValue;

        string ICallbackEventHandler.GetCallbackResult()
        {
            Control control = GetDropDownList(parentSelectValue,string.Empty);
            return GetControlHTML(control) + "|" + DropDownListValueInputId + "|" + SpanId;
        }


        void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
        {
            this.parentSelectValue = eventArgument;
        }

        #endregion

        public string Style { get; set; }

        protected string SpanId
        {
            get { return this.ClientID + "Span"; }
        }

        protected virtual string DropDownListValueInputId
        {
            get
            {
                return this.ClientID;
            }
        }

        private string selectPath;
        public string SelectPath
        {
            get 
            {
                string value = Page.Request.Form[DropDownListValueInputId];
                if (string.IsNullOrEmpty(value))
                    value = selectPath;
                return (string.IsNullOrEmpty(value))?string.Empty:value.TrimEnd('/'); 
            }
            set
            {
                selectPath = value;
            }
        }

        public string SelectValue
        {
            get 
            { 
                string[] label=SelectPath.Split('/');
                return label[label.Length - 1];
            }
        }

        public int Rows { get; set; }

        public string DropDownListStyle { get; set; }
    }
}
